using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Threading;

namespace BookBarter
{
    public class BookHave : BookInst
    {
        //class variables
        private static List<BookHave> bookHaves = new List<BookHave>();
        private Guid haveid;

        //class properties
        public Guid ID
        {
            get
            {
                return haveid;
            }
            private set
            {
                haveid = value;
            }
        }
        public static List<BookHave> BookHaves
        {
            get { return BookHave.bookHaves; }
            set { BookHave.bookHaves = value; }
        }

        //temporary for testing purposes
        public BookHave(Guid haveid, Condition cond, Person owner, Book book, String nothing)
            : base(cond, owner, book)
        {
            this.ID = haveid;
        }

        //constructor
        private BookHave(Guid haveid, Condition cond, Person owner, Book book)
            : base(cond, owner, book)
        {
            this.ID = haveid;
        }

        /// <summary>
        /// Creates a new book that someone has
        /// </summary>
        /// <param name="owner">Who has the book</param>
        /// <param name="book">The book they have</param>
        /// <param name="cond">The condition it is in</param>
        /// <returns></returns>
        public static BookHave CreateBookHave(Person owner, Book book, Condition cond)
        {
            BookHave newBH = null;
            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;

            //try to run the stored procedure to add the new bookHave
            SqlCommand query = new SqlCommand("EXEC add_book_have @userid, @bookid, @condition", cnx);
            query.Parameters.Add("@userid", System.Data.SqlDbType.VarChar);
            query.Parameters.Add("@bookid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters.Add("@condition", System.Data.SqlDbType.VarChar);
            query.Parameters["@userid"].SqlValue = owner.UserId;
            query.Parameters["@bookid"].SqlValue = book.ID;
            query.Parameters["@condition"].SqlValue = Enum.GetName(typeof(Condition), cond);

            //execute the query
            SqlDataReader result = query.ExecuteReader();
            try
            {
                //set info
                if (result.Read())
                {
                    if (result.IsDBNull(result.GetOrdinal("haveid")))
                        throw new MalformedBookHaveRecord("NULL where data is expected for record ID.");
                    newBH = BookHave.GetBookHave(result.GetGuid(result.GetOrdinal("haveid")));
                }
                //else - the creation failed
                else
                    throw new NewBookHaveException("The bookHave was not created!");
            }
            finally
            {
                result.Close();
            }
            bookHaves.Add(newBH);
            //if we are here... return the book have object
            return newBH;
        }

        /// <summary>
        /// Gets bookHave information for a specific guid
        /// </summary>
        /// <param name="haveid">guid of the BookHave</param>
        /// <returns>The bookHave requested</returns>
        public static BookHave GetBookHave(Guid haveid)
        {
            foreach (BookHave bh in bookHaves)
                if (bh.ID.Equals(haveid))
                    return bh;
            BookHave newBH = null;

            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;

            //create the query
            SqlCommand query = new SqlCommand("EXEC get_book_have @haveid", cnx);
            query.Parameters.Add("@haveid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters["@haveid"].SqlValue = haveid;

            //execute the query
            SqlDataReader result = query.ExecuteReader();
            try
            {
                //set info
                if (result.Read())
                {
                    Person userid = Person.GetPerson(result.GetString(result.GetOrdinal("userid")));
                    Book bookid = Book.GetBook(result.GetGuid(result.GetOrdinal("bookid")));
                    Condition cond = BookInst.LookupCondition(result.GetString(result.GetOrdinal("condition")));
                    newBH = new BookHave(haveid, cond, userid, bookid);
                }
                //else - the Have is INVALID
                else
                    throw new NoSuchBookHave("The bookHave does not exist!");
            }
            finally
            {
                result.Close();
            }
            //if we are here... return the book have object
            bookHaves.Add(newBH);
            return newBH;
        }

        /// <summary>
        /// Saves the bookHave to the database
        /// </summary>
        public void Save()
        {
            //grab connection to dbms
            SqlConnection cnx = DatabaseConnectionManager.Current.Connection;

            //create query to update the bookHave
            SqlCommand query = new SqlCommand("EXEC update_book_have @haveid, @userid, @bookid, @condition", cnx);
            query.Parameters.Add("@haveid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters.Add("@userid", System.Data.SqlDbType.VarChar);
            query.Parameters.Add("@bookid", System.Data.SqlDbType.UniqueIdentifier);
            query.Parameters.Add("@condition", System.Data.SqlDbType.VarChar);
            query.Parameters["@haveid"].SqlValue = this.ID;
            query.Parameters["@userid"].SqlValue = this.Person.UserId;
            query.Parameters["@bookid"].SqlValue = this.Book.ID;
            query.Parameters["@condition"].SqlValue = Enum.GetName(typeof(Condition), this.Condition);

            //execute the query
            query.ExecuteNonQuery();
        }
    }
}
